<template>
  <h2>vue3 + ts + compositionApi</h2>

  <h4>数字转字符串</h4>
  <p>
    <span>{{ num }}</span>
    <button @click="fn">转字符串</button>
  </p>

  <hr />

  <h4>计数器</h4>
  <p>
    <span>count: {{ count }}</span>
    <button @click="add(1)">count+1</button>
    <button @click="add(2)">count+2</button>
  </p>

  <hr />

  <h4>todolist</h4>
  <input type="text" v-model="value" />
  <button @click="push">添加</button>
  <ul>
    <li v-for="item in list" :key="item.id">
      {{ item.name }} - <button @click="remove(item.id)">删除</button>
    </li>
  </ul>

  <hr />

  <h4>数据请求</h4>
  <ul>
    <li v-for="item in arr" :key="item.id">{{ item.nm }}</li>
  </ul>

  <hr />

  <h4>计算属性和监听属性</h4>
  <p>count2: {{ count2 }}</p>
  <button @click="count2++">count2++</button>
  <p>doubleCount2: {{ doubleCount2 }}</p>

  <hr />

  <h4>事件处理</h4>
  <input type="text" @input="change" />

  <hr />

  <Child a="123" @b="fn2" />
</template>

<script lang="ts" setup>
import { ref, onMounted, computed, watch, reactive, provide } from "vue";
import Child from "./Child.vue";

// 数字转字符串
// 当使用ref的时候，可以用泛型的方式传入变量的类型
const num = ref<number | string>(123);
// 函数（方法）建议加上返回值的类型
const fn = (): void => {
  num.value = "hello";
};

// 计数器
const count = ref<number>(10);
const add = (n: number) => {
  count.value += n;
};

// todolist功能
const value = ref<string>("");
interface ListItemType {
  id: number;
  name: string;
  sex?: number;
}
const list = ref<ListItemType[]>([
  {
    id: 1,
    name: "zhangsan",
  },
  {
    id: 2,
    name: "lisi",
  },
]);
const push = () => {
  if (value.value) {
    list.value.push({
      id: new Date().getTime(),
      name: value.value,
    });
    value.value = "";
  }
};
const remove = (id: number) => {
  list.value = list.value.filter((item: ListItemType) => item.id !== id);
};

// 数据请求
interface ArrItemType {
  id: number;
  nm: string;
  [propname: string]: any; // 索引签名
}
const arr = ref<ArrItemType[]>([]);
onMounted(() => {
  fetch("http://118.24.239.63:3000/api/rated/list")
    .then((response) => response.json())
    .then((res) => {
      if (res.success) {
        arr.value = res.data;
      }
    });
});

// 计算属性和监听器
const count2 = ref<number>(10);
// 计算属性的类型的写法和ref是一样的
const doubleCount2 = computed<number>(() => {
  return count2.value * 2;
});
watch(count2, (val: number, oldVal: number): void => {
  console.log("count2改变了");
});

// 事件处理
// event事件对象的类型
const change = (e: Event) => {
  console.log("input改变了", (e.target as HTMLInputElement).value);
};

// reactive的类型，不需要用泛型，直接给前面的对象加（interface）
interface StateType {
  username: string;
  password: string;
}
const state: StateType = reactive({
  username: "admin",
  password: "123",
});
console.log(state.username);
console.log(state.password);

const fn2 = (n: number) => {
  console.log("fn2", n);
  return "abc";
};

provide("name", "zhangsan");
</script>
